# encoding: utf-8
"""
    ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    created by lane.chang on '13/05/2024'
    comment: 窗体的一些共通方法
"""
from datetime import datetime as dt

from PyQt5.QtWidgets import QTableView
from PyQt5.QtGui import QStandardItemModel, QStandardItem, QBrush, QFont
from PyQt5.QtCore import Qt

from project.third_part.okex import KLine, Okex
from project.model.digiccy import AlgoOrder, ConfigInfo
from project.lib.common import okex_client, okex_trade_client, with_session


class CommonService:

    @staticmethod
    @with_session()
    def flush_okex_client(session=None):
        """
        :return:
        """
        config_infos = session.query(ConfigInfo).filter(ConfigInfo.code.in_(['api_key_data', 'secret_key_data', 'passphrase_data'])).all()
        config_info_map = {v.code: v.value for v in config_infos}

        certify = dict()
        certify['api_key'] = config_info_map['api_key_data']
        certify['api_secret_key'] = config_info_map['secret_key_data']
        certify['passphrase'] = config_info_map['passphrase_data']

        okex_client.flag = '0'
        okex_client.certify = certify

    @staticmethod
    @with_session()
    def flush_okex_trade_client(session=None):
        """
        :return:
        """
        config_infos = session.query(ConfigInfo).filter(ConfigInfo.code.in_(['trading_mode', 'api_key_trade', 'secret_key_trade', 'passphrase_trade'])).all()
        config_info_map = {v.code: v.value for v in config_infos}

        certify = dict()
        certify['api_key'] = config_info_map['api_key_trade']
        certify['api_secret_key'] = config_info_map['secret_key_trade']
        certify['passphrase'] = config_info_map['passphrase_trade']

        okex_trade_client.flag = '0' if config_info_map['trading_mode'] == 'real' else '1'
        okex_trade_client.certify = certify

    @staticmethod
    def convert_klines_to_table_fm(klines: list[KLine], reverse=False):
        """ 将日 K 线(5M)转化成TableView可加载的共通格式
        :param klines:
        :param reverse:
        :return:
        """
        # 按交易事件正排序 主要为了计算当日最高，当日最低维度
        klines.sort(key=lambda x: x.trading_ts)

        records = list()
        trading_date = None
        highest_price = lowest_price = 0.0
        for kline in klines:
            if kline.trading_date != trading_date:
                trading_date = kline.trading_date
                highest_price = kline.highest_price_fm
                lowest_price = kline.lowest_price_fm
            else:
                if kline.highest_price_fm >= highest_price:
                    highest_price = kline.highest_price_fm
                if kline.lowest_price_fm <= lowest_price:
                    lowest_price = kline.lowest_price_fm
            kline.highest_price = highest_price
            kline.lowest_price = lowest_price

            records.append(
                [
                    {'header': '时间', 'align': 'center', 'value': dt.fromtimestamp(int(kline.trading_ts) / 1000).strftime('%Y-%m-%d %H:%M')},
                    {'header': '5M开盘', 'align': 'right', 'value': kline.opening_price_fm},
                    {'header': '5M收盘', 'align': 'right', 'value': kline.closing_price_fm},
                    {'header': '5M最低', 'align': 'right', 'value': kline.lowest_price_fm},
                    {'header': '5M最高', 'align': 'right', 'value': kline.highest_price_fm},
                    {'header': '今日最低', 'align': 'right', 'value': kline.lowest_price},
                    {'header': '今日最高', 'align': 'right', 'value': kline.highest_price},
                    {'header': '点阵负值', 'align': 'right', 'value': 0},
                    {'header': '点阵正值', 'align': 'right', 'value': 0},
                    {'header': '点阵终值', 'align': 'right', 'value': 0},
                    {'header': '状态', 'value': ''},
                    {'header': '风控日志', 'value': ''}
                ]
            )

        if reverse:
            records.sort(key=lambda x: x[0]['value'], reverse=reverse)

        return records

    @staticmethod
    def convert_algo_orders_to_table(algo_orders: list[AlgoOrder]):
        """
        :param algo_orders:
        :return:
        """
        records = []
        for algo_order in algo_orders:
            records.append(
                [
                    {'header': '交易币种', 'align': 'center', 'value': algo_order.inst_id},
                    {'header': '委托时间', 'align': 'center', 'value': algo_order.ctime.strftime('%Y-%m-%d %H:%M:%S')},
                    {'header': '交易方向', 'align': 'center', 'value': algo_order.algo_price},
                    {'header': '委托数量', 'align': 'right', 'value': algo_order.count},
                    {'header': '委托价格', 'align': 'right', 'value': algo_order.algo_price},
                    {'header': '触发价格', 'align': 'right', 'value': algo_order.trigger_price},
                    {'header': '杠杆倍数', 'align': 'center', 'value': algo_order.lever},
                    {'header': '委托类型', 'align': 'center', 'value': '计划委托 限价委托'},
                ]
            )

        return records

    @staticmethod
    def refresh_table(table: QTableView, records):
        """ 刷新指定table view的展示结果集
        :param table: 指定table
        :param records: 结果集
        :return:
        """
        if not table:
            return

        # 设置 header 字体大小
        font = QFont()
        font.setPointSize(14)  # 设置字体大小
        table.setEditTriggers(QTableView.NoEditTriggers)
        # 2. 整行选中（好看，非必须）
        table.setSelectionBehavior(QTableView.SelectRows)
        table.setSelectionMode(QTableView.SingleSelection)
        table.horizontalHeader().setFont(font)
        table.setAlternatingRowColors(True)

        model = table.model()
        if not isinstance(model, QStandardItemModel):
            model = QStandardItemModel()
            table.setModel(model)

        model.clear()  # 1. 清空旧数据+表头
        if not records:  # 无数据直接返回
            return

        # 2. 动态列数 = 字典 key 数
        headers = [v.get('header') for v in records[0]]
        model.setColumnCount(len(headers))
        model.setHorizontalHeaderLabels(headers)

        # 3. 逐行填充
        for row, rec in enumerate(records):
            items = []
            for v in rec:
                item = QStandardItem()
                if v.get('align') == 'center':
                    item.setTextAlignment(Qt.AlignCenter)
                elif v.get('align') == 'left':
                    item.setTextAlignment(Qt.AlignLeft)
                elif v.get('align') == 'right':
                    item.setTextAlignment(Qt.AlignRight)

                value = v.get('value')
                # 百分比显示
                if v.get('is_percent', False):
                    item.setToolTip(str(value))
                    item.setData(f'{value * 100:.2f}%', Qt.DisplayRole)
                    item.setForeground(QBrush(Qt.red if value < 0 else Qt.darkGreen))
                # 浮点精度展示
                elif isinstance(value, float):
                    item.setToolTip(str(value))
                    item.setData(f'{round(value, 10)}', Qt.DisplayRole)
                elif isinstance(value, int):
                    item.setData(f'{value}', Qt.DisplayRole)
                elif isinstance(value, str):
                    item.setText(value)

                items.append(item)
            model.appendRow(items)

        # # 4. 可选：自适应列宽
        table.resizeColumnsToContents()
